const express = require('express');
const bodyParser = require('body-parser');
const { v4: uuidv4 } = require('uuid');

const db = require("./database.js")
const { selectUserByToken, selectUserByUsername, selectUserByUserId, insertUser, updateUserToken, updateUserNickname } = require("./user.js")
const { selectNewsList, selectNewsByNewsId } = require("./news.js")
const { selectAddrListByUserId, insertAddr, deleteAddr, updateAddr, updateAddrDefault, selectAddrByAddrId } = require("./addr.js")
const { selectProdList, selectProdListSelections, selectProdByProdId, selectProdGroupList, selectProdSaleByProdId } = require("./prod.js")
const { selectCartListByUserId, selectCartByUserIdAndProdId, updateCartAmount, insertCart, deleteCart, selectCartByCartIdArray } = require("./cart.js")
const { selectOrderByOrderId, selectOrderListByUserId, insertOrder, selectOrderProdByOrderId, insertOrderProd, updateOrderStatus } = require("./order.js")
const { insertFeedback } = require("./feedback.js")

const port = 8000;

const app = express();
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/user/register', async (req, res, next) => {
  const username = req.body.username
  const password = req.body.password
  const user = await selectUserByUsername(username)
  if (user != null) {
    res.send({ code: 500, msg: "用户名已存在", data: null })
    return
  }
  await insertUser({ username: username, password: password })
  res.send({ code: 200, msg: "", data: null })
})

app.post('/user/login', async (req, res, next) => {
  const username = req.body.username
  const password = req.body.password
  const user = await selectUserByUsername(username)
  if (user == null || password !== user.password) {
    res.send({ code: 500, msg: "用户名或密码错误", data: null })
    return
  }
  // 登录成功创建token
  const token = uuidv4();
  await updateUserToken({ user_id: user.user_id, token: token })
  const data = { token: token }
  res.send({ code: 200, msg: "", data: data })
})

app.get('/user/info', async (req, res, next) => {
  const token = req.get("Authorization")
  const user = await selectUserByToken(token)
  if (user == null) {
    res.send({ code: 200, msg: "请先登录您的账号", data: null })
    return
  }
  res.send({ code: 200, msg:"success", data: user })
})

app.put('/user/update', async (req, res, next) => {
  const nickname = req.body.nickname
  const token = req.get("Authorization")
  const user = await selectUserByToken(token)
  if (user == null) {
    res.send({ code: 200, msg: "请先登录您的账号", data: null })
    return
  }
  await updateUserNickname({ user_id: user.user_id, nickname: nickname })
  res.send({ code: 200, msg: "" })
})

app.get('/prod/items', async (req, res, next) => {
  const query = req.query
  let prodList = await selectProdList(query)
  for (let prod of prodList) {
    const prod_id = prod.prod_id
    const saleList = await selectProdSaleByProdId(prod_id)
    prod.saleList = saleList
  }
  res.send({ code: 200, msg:"", data: prodList })
});

app.get('/prod/selections', async (req, res, next) => {
  const list = await selectProdListSelections()
  res.send({ code: 200, msg:"success", data: list });
});

app.get('/prod/:prod_id/info', async (req, res, next) => {
  const prod_id = req.params.prod_id
  let prod = await selectProdByProdId(prod_id)
  const saleList = await selectProdSaleByProdId(prod_id)
  prod.saleList = saleList
  res.send({ code: 200, msg:"success", data: prod });
});

app.get('/prod/groups', async (req, res, next) => {
  const groups = await selectProdGroupList()
  res.send({ code: 200, msg: '', data: groups });
});

app.get('/cart/list', async (req, res, next) => {
  const token = req.get("Authorization")
  const user = await selectUserByToken(token)
  if (user == null) {
    res.send({ code: 300, msg: "请先登录您的账号", data: null })
    return
  }
  const user_id = user.user_id
  const list = await selectCartListByUserId(user_id)
  res.send({ code: 200, msg: "success", data: list })
});

app.post('/cart', async (req, res, next) => {
  const token = req.get("Authorization")
  const user = await selectUserByToken(token)
  if (user == null) {
    res.send({ code: 300, msg: "请先登录您的账号", data: null })
    return
  }
  const user_id = user.user_id
  const prod_id = req.body.prod_id
  const amount = 1
  const cart = await selectCartByUserIdAndProdId(user_id, prod_id)
  if (cart == null) {
    await insertCart({ user_id: user_id, prod_id: prod_id, amount: amount })
  } else {
    await updateCartAmount(cart.cart_id, cart.amount + amount)
  }
  res.send({ code: 200, msg: "" })
})

app.put('/cart', async (req, res, next) => {
  const cart_id = req.body.cart_id
  const amount = req.body.amount
  await updateCartAmount(cart_id, amount)
  res.send({ code: 200, msg: "" })
})

app.delete('/cart/:cart_id', async (req, res, next) => {
  const cart_id = req.params.cart_id
  await deleteCart(cart_id)
  res.send({ code: 200, msg: "" })
})

app.post('/addr/add', async (req, res, next) => {
  const name = req.body.name
  const address = req.body.address
  const phone_number = req.body.phone_number
  const isDefault = req.body.isDefault
  const token = req.get("Authorization")
  const user = await selectUserByToken(token)
  if (user == null) {
    res.send({ code: 200, msg: "请先登录您的账号", data: null })
    return
  }
  
  if (isDefault != null && isDefault) {
    const addrList = await selectAddrListByUserId(user.user_id)
    for (const addr of addrList) {
      if (addr.is_default == 1) {
        await updateAddrDefault({ addr_id: addr.addr_id, is_default: 0 })
      }
    }
  }
  const is_default = req.body.isDefault != null && req.body.isDefault ? 1 : 0
  await insertAddr({ user_id: user.user_id, name: name, address: address, phone_number: phone_number, is_default: is_default })
  res.send({ code: 200, msg: "" })
});

app.get('/addr/:addr_id/info', async (req, res, next) => {
  const addr_id = req.params.addr_id
  let addr = await selectAddrByAddrId(addr_id)
  addr.isDefault = addr.is_default == 1
  res.send({ code: 200, msg: "", data: addr })
})

app.delete('/addr/:addr_id/delete', async (req, res, next) => {
  const addr_id = req.params.addr_id
  const addr = await selectAddrByAddrId(addr_id)
  if (addr.is_default == 1) {
    res.send({ code: 201, msg: "默认地址不可删除" })
    return
  }
  await deleteAddr(addr_id)
  res.send({ code: 200, msg: "" })
})

app.put('/addr/update', async (req, res, next) => {
  const addr_id = req.body.addr_id
  const name = req.body.name
  const address = req.body.address
  const phone_number = req.body.phone_number
  const isDefault = req.body.isDefault
  if (isDefault != null && !isDefault) {
    const addr = await selectAddrByAddrId(addr_id)
    if (addr.is_default == 1) {
      res.send({ code: 201, msg: "默认地址不可删除" })
      return
    }
  }
  const is_default = req.body.isDefault != null && req.body.isDefault ? 1 : 0
  await updateAddr({ addr_id: addr_id, name: name, address: address, phone_number: phone_number, is_default: is_default })
  res.send({ code: 200, msg: "" })
})

app.get('/addr/list', async (req, res, next) => {
  const token = req.get("Authorization")
  const user = await selectUserByToken(token)
  if (user === null) {
    res.send({ code: 204, msg: "请先登录您的账号", data: null })
    return
  }
  const user_id = user.user_id
  const addrList = await selectAddrListByUserId(user_id)
  res.send({ code: 200, msg: "OK", data: addrList })
})

app.get('/order/list', async (req, res, next) => {
  const token = req.get("Authorization")
  const user = await selectUserByToken(token)
  if (user == null) {
    res.send({ code: 300, msg: "请先登录您的账号", data: null })
    return
  }
  const user_id = user.user_id
  const orderList = await selectOrderListByUserId(user_id)
  let data = []
  for (const order of orderList) {
    const prodList = await selectOrderProdByOrderId(order.order_id)
    data.push({ 
      order_id: order.order_id,  
      name: order.name,  
      phone_number: order.phone_number,  
      address: order.address,  
      price: order.price,
      status: order.status,
      create_time: order.create_time,
      prodList: prodList
    })
  }
  res.send({ code: 200, msg: "", data: data })
})

app.post('/order/create', async (req, res, next) => {
  const addr_id = req.body.addr_id
  if (addr_id == null) {
    if (addr_id == null) {
      res.send({ code: 500, msg: "请先选择收货地址", data: null })
      return
    }
  }
  const token = req.get("Authorization")
  const user = await selectUserByToken(token)
  if (user == null) {
    res.send({ code: 300, msg: "请先登录您的账号", data: null })
    return
  }
  const user_id = user.user_id
  const addr = await selectAddrByAddrId(addr_id)
  const name = addr.name
  const address = addr.address
  const phone_number = addr.phone_number

  if (req.body.cart_id_array != null) {
    const cart_id_array = req.body.cart_id_array
    const cartList = await selectCartByCartIdArray(cart_id_array)
    let price = 0
    for (const cart of cartList) {
      price += cart.amount * Number(cart.n_price)
    }
    const create_time = new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
    const order_id = uuidv4();
    const order = { order_id: order_id, user_id: user_id, name: name, address: address, phone_number: phone_number, price: price, status: 0, create_time: create_time }
    await insertOrder(order)
    for (const cart of cartList) {
      const prod = { order_id: order_id, prod_id: cart.prod_id, amount: cart.amount, price: cart.n_price }
      await insertOrderProd(prod)
      await deleteCart(cart.cart_id)
    }
    res.send({ code: 200, msg: "", data: order })
  } else if (req.body.prod != null) {
    const prod_id = req.body.prod.prod_id
    const amount = req.body.prod.amount
    const prod = await selectProdByProdId(prod_id)
    const price = prod.n_price * amount
    const create_time = new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
    const order_id = uuidv4();
    const order = { order_id: order_id, user_id: user_id, name: name, address: address, phone_number: phone_number, price: price, status: 0, create_time: create_time }
    await insertOrder(order)
    await insertOrderProd({ order_id: order_id, prod_id: prod_id, amount: amount, price: price })
    res.send({ code: 200, msg: "", data: order })
  } else {
    res.send({ code: 500, msg: "参数错误", data: null })
  }
});

app.get('/order/:order_id/pay', async (req, res, next) => {
  const order_id = req.params.order_id
  const order = await selectOrderByOrderId(order_id)
  if (order == null) {
    res.send({ code: 500, msg: "订单不存在" })
    return
  }
  if (order.status !== 0) {
    res.send({ code: 500, msg: "订单已支付" })
    return
  }
  // 生成预支付参数
  const data = { order_id: order_id, qrcode: '/img/qrcode_for_test.png', price: order.price }
  res.send({ code: 200, msg: "", data: data })
})

app.put('/order/:order_id/paid', async (req, res, next) => {
  const order_id = req.params.order_id
  const order = await selectOrderByOrderId(order_id)
  // 演示环境无法付款，无第三方回调，直接修改订单状态
  await updateOrderStatus({ order_id: order_id, status: 1 })
  res.send({ code: 200, msg: "" })
})

app.put('/order/:order_id/cancel', async (req, res, next) => {
  const order_id = req.params.order_id
  await updateOrderStatus({ order_id: order_id, status: 4 })
  res.send({ code: 200, msg: "" })
})

app.put('/order/:order_id/finish', async (req, res, next) => {
  const order_id = req.params.order_id
  await updateOrderStatus({ order_id: order_id, status: 3 })
  res.send({ code: 200, msg: "" })
})

app.get('/news', async (req, res, next) => {
  const news = await selectNewsList()
  res.send({ code: 200, msg: '', data: news })
});

app.get('/news/:news_id/content', async (req, res, next) => {
  const news_id = req.params.news_id
  const news = await selectNewsByNewsId(news_id)
  res.send({ code: 200, msg: '', data: news })
});

app.post('/feedback', async (req, res, next) => {
  const phone_number = req.body.phone_number
  const content = req.body.content
  const create_time = new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
  await insertFeedback({ phone_number: phone_number, content: content, create_time: create_time })
  res.send({ code: 200, msg: '' })
});

app.listen(port, () => {
  console.log('We are live on ' + port);
});
